package api

import (
	"context"
	"encoding/json"
	"fmt"
	"longmen/server/config/global"
	"longmen/server/internal/rpc/tencentim/chat"
	"longmen/server/internal/rpc/tencentim/config"
	services2 "longmen/server/pkg/common/services"
	"longmen/server/pkg/db/mysql/models/models_main"
	"longmen/server/pkg/db/redis/cache"
	"time"

	"github.com/spf13/cast"

	"longmen/server/pkg/common/api_models"
)

type ExternalAPI struct {
}

func InitAPI() {
	if api != nil {
		global.Log.Fatal("[ExternalAPI] already initialized")
	}
	api = &ExternalAPI{}

	//var t = http.DefaultTransport.(*http.Transport).Clone()
	//t.MaxIdleConns = cfg.ExternalAPI.MaxIdleConnections
	//t.MaxConnsPerHost = cfg.ExternalAPI.MaxConnectionsPerHost
	//t.MaxIdleConnsPerHost = cfg.ExternalAPI.MaxIdleConnectionsPerHost
	//
	////httpClient = &http.Client{
	////	Timeout:   cfg.ExternalAPI.RequestTimeout * timehelper.Millisecond,
	////	Transport: t,
	////}
}

func GetAPI() *ExternalAPI {
	if api == nil {
		global.Log.Fatal("[ExternalAPI] not initialized")
	}
	return api
}

// AnchorCheck 检查主播的合法化
func (a *ExternalAPI) AnchorCheck(anchorId int) (*api_models.AnchorCheckResp, error) {
	_, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)
	defer cancelFunc()
	services2.GetGiftList()
	rsp, err := services2.AnchorCheck(&api_models.LiveConfigReq{Anchorid: anchorId})
	return rsp, err
}

// GetRoomConfig 取得房间配置
func (a *ExternalAPI) GetRoomConfig(roomId int) (*config.RoomConfig, error) {
	ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)
	defer cancelFunc()
	key := genRoomIdCacheKey("liveConfig", roomId)
	r := &chat.RoomConfigResult{}
	err := a.getCachedData(ctx, key, r)
	if err != nil || r == nil {
		rsp, err := services2.LiveConfig(&api_models.LiveConfigReq{Anchorid: roomId})
		if err != nil {
			global.Log.Errorf("error %v", err)
			return nil, err
		} else {
			r.Status = rsp.Status
			r.Heat = rsp.Heat
			r.GiftFactor = int(rsp.GiftFactor)
			r.GiftTime = int(rsp.GiftTime)
			r.Populaarsuse = int(rsp.Populaarsuse)
			r.SumbumistegurK = int(rsp.SumbumistegurK)
			r.Status = uint8(rsp.Status)
			r.LiveId = int(rsp.Liveid)
			r.Nickname = rsp.Nickname
			r.MatchId = int(rsp.Matchid)
			r.OfficialType = uint8(rsp.OfficialType)
			// 将查询结果缓存起来
			_ = a.cacheData(ctx, key, r, time.Second*10)
		}

	}
	c := &config.RoomConfig{}
	c.Rand = r.Heat
	c.GiftFactor = r.GiftFactor
	c.GiftTime = r.GiftTime
	c.Populaarsuse = r.Populaarsuse
	c.SumbumistegurK = r.SumbumistegurK
	c.Status = r.Status
	c.LiveId = r.LiveId
	c.AnchorName = r.Nickname
	c.MatchId = r.MatchId
	c.OfficialType = r.OfficialType
	return c, nil
}

// GetMatchData 取得比赛数据
func (a *ExternalAPI) GetMatchData(roomId int) (*chat.MatchDataResult, error) {
	ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)
	defer cancelFunc()
	key := genRoomIdCacheKey("matchDataKey_", roomId)
	r := &chat.MatchDataResult{}
	err := a.getCachedData(ctx, key, r)
	if err != nil || r == nil {
		resp, err := services2.AnchorMatchInfo(&api_models.MatchSimpleDataReq{Anchorid: uint32(roomId)})
		if err != nil {
			return nil, err
		}
		_ = a.cacheData(ctx, key, resp, 10000*time.Millisecond)
		return &chat.MatchDataResult{
			HomeName:        resp.HomeName,
			AwayName:        resp.AwayName,
			Id:              int(resp.Id),
			Time:            resp.Time,
			KickoffTime:     resp.KickoffTime,
			HomeId:          int(resp.HomeId),
			AwayId:          int(resp.AwayId),
			HomeScore:       int(resp.HomeScore),
			AwayScore:       int(resp.AwayScore),
			HomeLogo:        resp.HomeLogo,
			AwayLogo:        resp.AwayLogo,
			Status:          resp.Status,
			CompetitionName: resp.CompetitionName,
		}, nil
	}
	return r, nil
}

// GetBannedUserList 取得禁言用户列表
func (a *ExternalAPI) GetBannedUserList(anchorId int, usr *chat.ClientUser) error {
	/*ctx, cancelFunc := context.WithTimeout(context.Background(), timehelper.Second*5)
	defer cancelFunc()
	resp, err := grpc_client.WebSocketClient.GetBanList(ctx, &pt.BanListReq{Anchorid: uint32(anchorId)})
	if err != nil {
		return nil, err
	}

	return &im.BannedUserResult{UserList: resp.GetUser()}, nil*/
	return nil
}

// BanUser 禁言或解除禁言
// 弃用，改为走tencent_im_api
func (a *ExternalAPI) BanUser(usr *chat.ClientUser, anchorId, banType, banUserId int, banTime int64) error {
	/*req := &pt.BanUserReq{
		Anchorid: uint32(anchorId),
		Type:     uint32(banType),
		Userid:   uint32(usr.SenderUid),
		BanUid:   uint32(banUserId),
		BanTime:  banTime,
	}
	global.Log.Debug(
		"BanUser req anchorId : ", uint32(anchorId),
		"Type: ", uint32(banType),
		"Userid: ", uint32(usr.SenderUid),
		"BanUid: ", uint32(banUserId),
		"BanTime: ", banTime,
	)
	ctx, cancelFunc := context.WithTimeout(context.Background(), timehelper.Second*5)
	defer cancelFunc()
	_, err := grpc_client.WebSocketClient.BanUser(ctx, req)
	if err != nil {
		return err
	}*/
	return nil
}

// ToggleAttentionAnchor 切换关注主播，成功返回粉丝数量和关注消息
func (a *ExternalAPI) ToggleAttentionAnchor(anchorId int, usr *chat.ClientUser) (*chat.AttentionAnchorResult, error) {
	_, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)
	defer cancelFunc()
	resp, err := services2.AttentAnchorOld(&api_models.AttentanchorReq{Anchorid: anchorId, Uid: uint32(usr.UserId)})
	if err != nil {
		return nil, err
	}
	return &chat.AttentionAnchorResult{FansCount: int(resp.FansCount), Type: int(resp.Type)}, nil
}

// ChatHistory 保存聊天历史 进nats 让worker处理
func (a *ExternalAPI) ChatHistory(content string, uid int, roomId int, chatId int64) error {

	var chatRecord models_main.ChatHistory
	chatRecord.RoomId = roomId
	chatRecord.Uid = uid
	chatRecord.Content = content
	chatRecord.Id = chatId
	chatRecord.CreateTime = time.Now().UnixMilli()
	chatRecord.Status = 1
	err := cache.PushChatNats(&chatRecord)
	//global.Log.Debugf("chatHistory:%v", chatRecord)
	if err != nil {
		global.Log.Errorf("push chatHistory err:%v", err)
	}
	return err
}

// 礼物列表
func (a *ExternalAPI) GetGiftList() (*api_models.GiftListResp, error) {
	_, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)
	defer cancelFunc()
	result, err := services2.GetGiftListOld()
	if err != nil {
		return nil, err
	}
	return result, nil
}

// 获取聊天最大id
func (a *ExternalAPI) GetChatMaxId() int64 {
	_, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)
	defer cancelFunc()
	resp, _ := services2.GetChatMaxId()
	return int64(resp.Id)
}

// 玩家背包
func (a *ExternalAPI) GetUserBackpack(uid int) (*api_models.UserBackpackResp, error) {
	resp, err := services2.GetUserBackpack(&api_models.UserBackpackReq{
		Uid: int32(uid),
	})
	return resp, err
}

// 道具列表
func (a *ExternalAPI) GetPropsList() (*api_models.PropsResp, error) {
	resp, err := services2.GetPorosList()
	return resp, err
}

// 用户详情,走的service
func (a *ExternalAPI) GetUserInfo(uid, anchorId int) (*api_models.UserInfoResp, error) {
	resp, err := services2.ChatRoomGetUserInfo(&api_models.UserInfoReq{
		Uid:      int32(uid),
		AnchorId: int64(anchorId),
	})
	//global.Log.Debugf("userInfo:%v,err:%v", resp, err)
	return resp, err
}

//// private

var api *ExternalAPI

func genRoomIdCacheKey(prefix string, roomId int) string {
	return fmt.Sprintf("%s%d", prefix, roomId)
}

func (a *ExternalAPI) getCachedData(ctx context.Context, key string, result interface{}) error {
	b, err := global.GetRds().Get(key).Bytes()
	if err != nil {
		return err
	}
	return json.Unmarshal(b, result)
}

func (a *ExternalAPI) cacheData(ctx context.Context, key string, result interface{}, expiration time.Duration) error {
	b, err := json.Marshal(result)
	if err != nil {
		return err
	}

	return global.GetRds().Set(key, b, expiration).Err()
}

func (a *ExternalAPI) GetUserBackPack(uid int) *chat.ChatProps {
	var chatProps chat.ChatProps
	exists, err := global.BloomExists(global.BLOOM_ID, cast.ToString(uid))
	if err != nil {
		global.Log.Errorf("bloom filter err:%v", err)
	}
	if !exists {
		return &chatProps
	}
	propsList, err := a.GetPropsList()
	if err != nil {
		return &chatProps
	}
	userBackPack, err := a.GetUserBackpack(uid)
	if err != nil {
		return &chatProps
	}

	for _, v := range userBackPack.UserBackpack {
		if v.PropsType == 2 {
			for _, l := range propsList.PropsList {
				if v.Gid == l.Id {
					props := &chat.Props{
						Name:  l.Name,
						Icon:  l.Icon,
						Style: l.Style,
					}
					switch l.Type {
					case 1:
						chatProps.Pendant = append(chatProps.Pendant, props)
					case 2:
						chatProps.Background = "" //l.Style
					case 3:
						chatProps.FontColor = "" //l.Style
					}
				}

			}
		}

	}
	return &chatProps
}

// GetUserRole 获取用户权限
func (a *ExternalAPI) GetUserRole(userId, anchorId int) int32 {
	req := &api_models.PermissionReq{
		UserId:   int64(userId),
		AnchorId: int64(anchorId),
	}
	exists, err := global.BloomExists(global.BLOOM_ID, cast.ToString(userId))
	if err != nil {
		global.Log.Errorf("bloom filter err:%v", err)
	}
	if !exists {
		return 1
	}

	permission, err := services2.ChatRoomPermission(req)
	global.Log.Debugf("GetUserRole uid:%v,rold:%v,anchorId:%v", userId, permission.Role, anchorId)
	if err != nil {
		return 1 //没有权限
	}
	return permission.Role
}
